home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-02-12 | 46.0 KB | 1,000 lines |
- ┼ND;
-
- ╫RITELN;
- ╫RITELN ('╩OB ├OMPLETED :-)');
-
- END;
-
- ╞OR ├OUNTER := 1 TO 3 DO
- ╫RITELN;
- █ ═AKE A BIT OF SPACE WHEN FINISHED :-) ▌
- END.
-
- ================================================================================
- ┬┴╬╦╔╬╟ ╧╬ ╟┼╧╙
-
- BY ╥OBERT ┴. ╦NOP ╩R.
-
- ╔. ╔NTRODUCTION
-
- ╟┼╧╙ WAS ORIGINALLY WRITTEN FOR THE ├OMMODORE 64. ╫HEN ┬ERKELEY ╙OFTWORKS
- CAME OUT WITH ╟┼╧╙128 (AND, FOR A TIME, IT WASN'T CLEAR THAT THEY WOULD; THEN,
- IT LOOKED LIKE THEY WOULD RELEASE A ╟┼╧╙128 THAT WOULDN'T SUPPORT THE 80
- COLUMN SCREEN; FINALLY, THE RELEASE OF ╟┼╧╙128 DID TURN OUT TO BE A FULL 128
- PROGRAM), IT WAS LARGELY COMPATIBLE WITH ╟┼╧╙64. ┴PPLICATIONS COULD SHARE
- DOCUMENTS (A GEO╨AINT FILE IS A GEO╨AINT FILE), AND EVEN MANY ╟┼╧╙64
- APPLIATIONS RUN ON THE 128 IN 40 COLUMNS. ╘HIS HERITAGE IS ALSO EVIDENT TO
- THE ╟┼╧╙ PROGRAMMER.
-
- ┴S WE ALL KNOW, THE ├-128 HAS TWO 64╦ ╥┴═ BANKS; THE ├-64 ONLY HAS ONE 64╦ ╥┴═
- "BANK." ╘HUS, OF COURSE, ALL OF ╟┼╧╙64 GOES INTO THAT ONE 64╦ ╥┴═ SPACE.
- ╘HIS INCLUDES THE ╦ERNAL AS WELL AS THE SPACE AVAILABLE TO APPLICATIONS. ╧NCE
- THE ╦ERNAL, GRAPHICS SCREENS, AND SO FORTH, HAVE CLAIMED THEIR ╥┴═, THE ╟┼╧╙
- PROGRAMMER IS LEFT WITH 23.75╦ OF MEMORY FROM $0400 TO $5FFF.
-
- ╘O A CURSORY "GLANCE," THE ╟┼╧╙128 PROGRAMMING ENVIRONMENT LOOKS VERY MUCH
- LIKE THE ╟┼╧╙64 PROGRAMMING ENVIROMENT. ┘OU STILL HAVE $0400 TO $5FFF
- AVAILABLE FOR APPLICATIONS; GRAPHICS SCREENS AND VARIABLES ARE IN THE SAME
- PLACE; THE ╦ERNAL JUMP TABLE IS THE SAME (WITH SOME 128 SPECIFIC ADDITIONS).
- ╫HAT HAPPENED TO THE OTHER 64╦ THAT THE 128 HAS AVAILABLE?
-
- ┴S IT TURNS OUT, THE CORE OF ╟┼╧╙128- INCLUDING THE APPLICATION PROGRAM SPACE,
- THE 40 COLUMN FOREGROUND AND BACKGROUND SCREEN, AND THE ╦ERNAL JUMP TABLE- ARE
- ALL IN THE 128'S ╥┴═ BLOCK 1, WHAT ╟┼╧╙ CALLS ╞RONT╥┴═. ╘O US 128 PROGRAMMERS
- USED TO ╥┴═ BLOCK 0 BEING THE "MAIN" ╥┴═ BLOCK, THIS MAY SOUND ODD. ╚OWEVER,
- IT ACTUALLY MAKES SENSE. ╞IRST OF ALL, SINCE ╟┼╧╙ IS AN OPERATING SYSTEM IN
- AND OF ITSELF, AND APPLICATIONS ALMOST NEVER NEED TO CALL THE ├128'S ╦ERNAL
- ROUTINES, THE APPLICATION NO LONGER NEEDS ACCESS TO ┬ANK 15. ╙ECOND, IT
- ALLOWS ╟┼╧╙128 TO KEEP MUCH OF ITS MEMORY MAP THE SAME AS ╟┼╧╙64; IT CAN USE
- THE MEMORY RANGE FROM $200-$3FF IN ╥┴═ 1 WITHOUT WORRYING ABOUT DISTURBING KEY
- SYSTEM ROUTINS LIKE ╙╘┴╞┴╥ WHICH ARE IN THE SAME MEMORY RANGE IN ╥┴═ 0.
-
-
- ╔╔. ┘EAH, ┘EAH, ┬UT ╫HAT ╚APPENED TO ╥┴═ 0 ┴NYWAY?
-
- ╔T'S STILL THERE. ╙OME OF ╥┴═ 0 IS USED BY ╟┼╧╙128 TO IMPROVE THE SYSTEM
- PERFORMANCE AND TO TAKE ADVANTAGE OF THE 128'S UNIQUE FEATURES. (╞OR
- INSTANCE, THE CODE FOR THE "SOFTWARE SPRITES" SEE ON THE 128'S 80 COLUMN
- SCREEN IS FOUND BENEATH $2000 IN ╥┴═ 0.) ╞ORTUNATELY, SOME SPACE DOES REMAIN
- AVAILABLE FOR AN APPLICATION TO USE. ╔N ╥┴═ 0, THE 32╦ MEMORY SPACE BETWEEN
- $2000 AND $9FFF IS NOT NORMALLY USED BY ╟┼╧╙, AND IS ┴╠═╧╙╘ AVAILABLE FOR
- APPLICATION USE [1].
-
- ╫HY DO ╔ SAY "ALMOST"? ╘HE PROBLEM IS DESK ACCESSORIES. ╫HEN ╟┼╧╙ 64 LOADS A
- DESK ACCESSORY (─┴), IT MUST LOAD IT INTO THE SAME APPLICATION SPACE AS THE
- APPLICATION LOADING THE ─┴. ╘HE MEMORY THAT THE ─┴ WILL USED IS FIRST SAVED
- TO DISK IN A SWAP FILE. ╒NDER ╟┼╧╙128, THE ROUTINE ╠D─ESK┴CC, INSTEAD OF
- SAVING A SWAP FILE TO DISK, COPIES THE MEMORY TO BE OVERWRITTEN BY THE ─┴ TO
- ╥┴═0 BETWEEN $2000 AND $9FFF. ╙O, IF YOUR APPLICATION USES ─┴'S (AND IT IS
- HIGHLY RECOMMENDED THAT MAJOR APPLICATIONS SUPPORT ─┴'S), YOU HAVE TO BE
- CAREFUL USING THE SPACE BETWEEN $2000 AND $9FFF. ┘OU CAN USE IT AS TEMPORARY
- SWAP SPACE WITHIN ROUTINES- BUT YOU CANNOT ASSUME THAT IT WILL REMAIN INTACT
- WHENEVER YOUR ROUTINE RETURNS TO THE ╟┼╧╙ ═AIN╠OOP WITH YOUR APPLICATION IN A
- STATE THAT WILL ALLOW THE LOADING OF ─┴'S.
-
- ╬OWADAYS, ╥┴═ 0 IS NOT THE BE-ALL AND END-ALL. ╟┼╧╙128 WAS WRITTEN FOR THE
- ├=128, NOT THE ├=256. ├ONSEQUENTLY, IF YOU HAVE EXPANDED YOUR 128 TO 256╦ OR
- 512╦ AS DESCRIBED IN THE ARTICLES BY ╥ICHARD ├URCIO IN ╘WIN ├ITIES 128 ╔SSUES
- #30 AND #31 [2,3], YOU HAVE FREE USE OF ╥┴═ 2-3 (256╦) OR ╥┴═ 2-7 (512╦).
- (╬OTE THAT YOU SHOULD NOT TOUCH ╥┴═ 4-7 ON A 512╦ 128 IF YOU WANT TO BE
- COMPATIBLE WITH TASK SWITCHING AS DESCRIBED IN ╘├128 #31. ┴LSO, ALTHOUGH ╟┼╧╙
- RIGHT NOW DOES NOT RUN IN THE 2ND 256╦, APPLICATIONS SHOULD NOT ASSUME THEY
- ARE IN THE 1ST 256╦, AND THUS SHOULD BE CAREFUL WITH THE 512╦ MODE BITS (4-5)
- IN THE ══╒ ╥AM ├ONFIGURATION ╥EGISTER (╥├╥), $D506.) ╫HILE THE NUMBER OF
- PEOPLE WITH 256╦ AND 512╦ 128'S IS NOW SMALL, YOU CAN BE SURE THAT IT WILL
- INCREASE WHEN THE PROMISED ┌╔╨ ACCELERATOR BOARD FOR THE 128 COMES OUT; THE
- CURRENT SPECS FOR THE ┌╔╨ BOARD INCLUDE PROVISIONS FOR MEMORY EXPANSION ON THE
- BOARD.
-
- ╥┴═ 2-3 PROVIDE ALMOST ANOTHER COMPLETE 128╦ AVAILABLE FOR YOUR APPLICATION TO
- USE. ╙O HOW DO YOU GO ABOUT ACCESSING THIS?
-
-
- ╔╔╔. ╙TORING ─ATA ╔N ╧THER ╥┴═ ┬LOCKS
-
- ╘HE MOST OBVIOUS USE FOR ╥┴═ BLOCKS OTHER THAN ╞RONT╥┴═ (WHICH IS THE ONLY
- BLOCK WHERE ╟┼╧╙ ╦ERNAL ROUTINES ARE AVAILABLE) IS AS DATA STORAGE. ╞OR
- INSTANCE, ONE COULD VISUALIZE A GEO╨AINT PREVIEWING UTILITY WHICH LOADS AND
- DECOMPACTS AN ENTIRE GEO╨AINT DOCUMENT AT ONCE TO ╥┴═ 2. (╘HE FULL
- DECOMPACTED GEO╨AINT DOCUMENT WOULD REQIRE 56.25╦.) ╧NE COULD THEN QUICKLY
- SCROLL THROUGH THE DOCUMENT BY JUST COPYING THE RELEVANT PORTIONS OF THE
- BITMAP FROM ╥┴═ 2 TO THE FOREGROUND SCREEN. ╧R, IF ONE WERE REALLY BOLD, ONE
- COULD JUST REDIRECT THE ╓╔├ SCREEN MEMORY TO THE RELEVANT RANGE IN ╥┴═2 USING
- THE PROPER ══╒ AND ╓╔├ REGISTERS. (╘HIS WOULD ACTULLY REQUIRE USE OF BOTH ╥┴═
- 2 AND 3, SINCE ╓╔├ SCREEN LOCATIONS ARE QUANTIZED TO 8╦; YOU LOSE THE USE OF
- THE HIGHEST 8╦, SINCE YOU DON'T WANT TO OVERWRITE THE ══╒ REGISTERS AT
- $FF00-$FF05; ADDITIONAL PRACTICAL CONSIDERATIONS MAKE USE OF THE LOWEST 8╦
- DIFFICULT.)
-
- ╟┼╧╙128 PROVIDES A FEW ROUTINES FOR EASILY MOVING DATA BETWEEN ╞RONT╥┴═ AND
- WHAT IT CALLS ┬ACK╥┴═ (BUT WE KNOW IT JUST MEANS ╥┴═ 0). ╚APPILY, THESE
- ROUTINES WORK QUITE ADMIRABLY WITH ╥┴═ 2 AND 3. (╘O ACCESS ╥┴═ 4-7, FIDDLE
- BITS 4 AND 5 OF THE ══╒ ╥├╥ TO MAKE THE DESIRED ╥┴═ BLOCKS APPEAR TO THE
- SYSTEM AS VIRTUAL ╥┴═ 2 AND ╥┴═ 3, THEN CALL THESE ROUTINES.) ╘HE CORE
- ROUTINE IS ─O┬╧P, WHICH IS SUMMARIZED BELOW [4]:
-
- ***********************************************************************
- ─O┬╧P=$C2EC: ├OPY/VERIFY MEMORY BETWEEN ╥┴═ BLOCKS ON THE ├-128.
-
- ╨ASS:
- R0 : ┴──╥1 - ADDRESS OF FIRST ("SOURCE") MEMORY RANGE
- R1 : ┴──╥2 - ADDRESS OF SECOND ("DESTINATION") MEMORY RANGE
- R2 : ├╧╒╬╘ - NUMBER OF BYTES TO OPERATE ON
- R3╠ : ┴1┬┴╬╦ - BANK OF ┴──╥1 (E.G. 1=╞RONT╥┴═, 0=┬ACK╥┴═)
- R3╚ : ┴2┬┴╬╦ - BANK OF ┴──╥2
- Y : ═╧─┼ - OPERATION TO PERFORM
-
-
- ╥ETURNS: R0-R3 UNCHANGED
-
- WHEN VERIFYING: X=$00 IF TWO RANGES MATCH, X=$FF IF THEY DON'T MATCH
-
-
- ─ESTROYS: A,X,Y
-
-
- ╘HE OPERATION MODE IS PASSED IN Y AS FOLLOWS:
-
- BIT0 BIT1 ─ESCRIPTION
- ---- ---- -----------
- 0 0 ═OVE FROM MEMORY AT ┴──╥1 TO MEMORY AT ┴──╥2
- 0 1 ═OVE FROM MEMORY AT ┴──╥2 TO MEMORY AT ┴──╥1
- 1 0 ╙WAP MEMORY AT ┴──╥1 AND ┴──╥2
- 1 1 ╓ERIFY (COMPARE) MEMORY AT ┴──╥1 AND ┴──╥2
- ***********************************************************************
-
- (R0, R1, ETC. ARE ALL THE STANDARD ┬╙╫ SYMBOLS DEFINED IN THE ╧FFICIAL ╟┼╧╙
- ╨ROGRAMMER'S ╥EFERENCE ╟UIDE [5], AND THAT COME IN THE FILE GEOS╙YM WITH
- GEO╨ROGRAMMER.)
-
- ╘HERE ARE A NUMBER OF ADDITIONAL ROUTINES WHICH ARE ALSO PROVIDED FOR
- PROGRAMMER CONVENIENCE WHICH AUTOMATICALLY SET THE ═╧─┼ IN THE Y REGISTER FOR
- YOU. ╔N ALL OF THESE ROUTINES, R0-R3 HAVE THE SAME MEANING AS THEY DO IN
- ─O┬╧P.
-
- ╥OUTINE ┴DDRESS ═╧─┼ ─ESCRIPTION
- ------- ------- ---- -----------
- ═OVE┬─ATA $C2E3 00 ├OPY DATA AT ┴──╥1 TO ┴──╥2
- ╙WAP┬─ATA $C2E6 10 ╙WAP DATA BETWEEN ┴──╥1 AND ┴──╥2
- ╓ERIFY┬─ATA $C2E9 11 ├OMPARE DATA AT ┴──╥1 AND ┴──╥2
-
- ╔ HAVE WRITTEN A SHORT DEMONSTRATION PROGRAM WHICH SHOWS THE USE OF ═OVE┬─ATA
- AND ╓ERIFY┬─ATA. ╘HE FULL SOURCE TO THIS PROGRAM, ┬═OVER, IS AVAILABLE
- THROUGH ANONYMOUS FTP AT TYBALT.CALTECH.EDU (IN THE RKNOP/HACKING.MAG
- DIRECTORY) AS WELL AS ELSEWHERE. ╔F YOU CAN'T FIND IT, CONTACT ME (ADDRESSES
- ARE BELOW). ╘HE SOURCE IS GEO╨ROGRAMMER CODE, IN GEO╫RITE 2.1 FORMAT. ┴LL OF
- THE FILES YOU NEED (EXCEPT GEOS╙YM AND GEOS═AC, WHICH COME WITH GEO╨ROGRAMMER)
- ARE IN THE BMOVER.SFX ARCHIVE.
-
- ╘HE FIRST FUNCTION OF ┬═OVER REPEATEDLY COPIES A SINGLE BLOCK ON ╥┴═ 1 TO
- SUCCESSIVE PARTS IN MEMORY IN ANY OTHER SPECIFIED BANK. ╘HE DESTINATION BANK,
- DESTINATION ADDRESSES, SIZE OF THE BLOCK TO MOVE, AND NUMBER OF TIMES TO COPY
- IT ARE ALL SET IN CONSTANTS FOUND AT THE BEGINNING OF THE SOURCE FILE ┬═OV┴SM.
- ╧NCE THE MOVES (WHICH USE ═OVE┬─ATA) HAVE ALL BEEN PERFORMED, ┬═OVER USES
- ╓ERIFY┬─ATA TO MAKE SURE THAT ALL OF THE BLOCKS WERE COPIED SUCCESFULLY.
-
- ╞OR INFORMATIONAL PURPOSES, ┬═OVER REPORTS THE AMOUNT OF TIME (IN TENTHS OF
- SECONDS) IT TOOK TO PERFORM ALL OF THE MOVES. (╞OR THIS, ╔ USE THE ├╔┴ #1 ╘╧─
- CLOCK, SAVING ITS VALUE AT THE BEGINNING AND END OF THE MOVE, AND SUBTRACTING
- TO GET THE DIFFERENCE.) ╔ RAN A TRIAL WHERE ╔ COPIED AN 8╦ BLOCK OF MEMORY TO
- ╥┴═ 2 7 TIMES (THUS FILLING 56╦ OF ╥┴═ 2). ╘HESE MOVES TOGETHER TOOK 1 SECOND
- AT 2 ═╚Z, AND 2.2 SECONDS AT 1 ═HZ. 56╦/SECOND MAY BE NO ─═┴, BUT IT'S FASTER
- THAN A BURST LOAD!
-
-
- ╔╓. ┼XECUTING ╥OUTINES ╔N ╧THER ┬ANKS
-
- ╙O, YOU'VE WRITTEN AN OBJECT ORIENTED DRAWING PROGRAM THAT STORES ITS LIST OF
- OBJECTS (32 BYTE RECORDS) IN ╥┴═ 2. ╧R, YOU HAVE A DATABASE THAT HAS RECORDS
- IN ╥┴═ 0. ┘OU WANT TO DELETE ONE RECORD AT THE BEGINNING OF THE LIST, WHICH
- MEANS MOVING ALL OF THE SUBSEQUENT RECORDS DOWN OVER THE MEMORY FREED UP BY
- THE DELETION. ╘HERE ARE A FEW THINGS YOU CAN DO. ╧NE, YOU CAN USE ├RAIG
- ┬RUCE'S DYNAMIC MEMORY ALLOCATION ROUTINES (HIGHLY RECOMMENDED). ╘WO, YOU CAN
- REPEATED DO ═OVE┬─ATA TO MOVE MEMORY FROM ╥┴═ 2 (OR 0) TO A BUFFER IN ╞RONT╥┴═
- AND BACK. ╧R, YOU CAN WRITE A SHORT MOVER ROUTINE IN THE ╥┴═ BANK WHERE ALL
- THE MOVING IS GOING TO HAPPEN.
-
- ╘HIS IS JUST AN EXAMPLE. ╧NE CAN VISUALIZE OTHER REASONS FOR CALLING ROUTINES
- IN OTHER ╥┴═ BANKS (WHAT ╔ CALL "EXTRABANKAL ROUTINES"). ╘HERE EXIST NO ╟┼╧╙
- ╦ERNAL ROUTINES FOR CALLING EXTRABANKAL ROUTINES. ┴DDITIONALLY, SINCE YOUR
- MAIN APPLICATION MEMORY IS IN ╥┴═ 1, YOU ARE INABLE TO USE THE 128 ╦ERNAL'S
- ╩╙╥╞┴╥ (WHICH RETURNS YOU TO ┬ANK 15). ╙O, WE ARE LEFT WITH IMPLEMENTING OUR
- OWN ╩╙╥╞┴╥.
-
- ╟┼╧╙128 NORMALLY OPERATES WITH ╬╧ COMMON MEMORY ENABLED. ╘HANKS TO ONE OF THE
- LESS WELL-KNOWN FEATURES OF THE ══╒, THERE IS NO NEED TO ENABLE COMMON MEMORY.
- ╘HE ══╒ ZERO PAGE REGISTERS ($D507 AND $D508) ALLOW YOU TO LOCATE THE ZERO
- PAGE THAT THE PROCESSOR SEES ANYWHERE IN ╥┴═ 0 OR ╥┴═ 1. ╫HAT THIS MEANS IS,
- NO MATTER WHAT YOUR MEMORY CONFIGURATION IS, THE PROCESSOR SEES ZERO PAGE IN
- THE ╥┴═ BLOCK SPECIFIED IN $D508. (╒NLESS YOU HAVE COMMON MEMORY ENABLE, IN
- WHICH CASE IT IS NOT A GOOD IDEA TO PUT ┌╨ IN ╥┴═ BLOCKS OTHER THAN ╥┴═ 0
- [6,7].) ╙O, ZERO PAGE IS EFFECTIVELY COMMON MEMORY!
-
- ╘HIS PROVIDES FOR THE POSSIBLITY OF COPYING TO ZERO PAGE A SHORT "SWITCHBOARD"
- ROUTINE, BASICALLY A REIMPLEMENTATION OF ╩╙╥╞┴╥, WHICH CONFIGURES THE SYSTEM
- FOR THE DESTINATION BANK, JSR'S TO A ROUTINE, RECONFIGURES THE SYSTEM FOR THE
- CALLING BANK, AND RTS'S.
-
- ╔ ALSO DEMONSTRATE THIS TECHNIQUE IN ┬═OVER. ╘HE SECOND FUNCTION OF ┬═OVER
- FIRST USES ═OVE┬─ATA TO COPY A ROUTINE TO $2000 IN ─┼╙╘┬┴╬╦ (WHICH IS SET
- RIGHT NOW IN THE SOURCE CODE TO ╥┴═ 0). ╔T THEN COPIES THE ROUTINE ┌╨╩╙╥ TO
- $02, WHICH STORES ─┼╙╘├╞╟ IN $FF00 AND JSR'S TO $2000. ╘HE ROUTINE AT $2000
- MOVES SOME DATA AROUND IN ─┼╙╘┬┴╬╦. ╧NCE ┌╨╩╙╥ HAS RETURNED THE PROGRAM FLOW
- TO ╞RONT╥┴═, ┬═OVER CALLS ╓ERIFY┬─ATA TO MAKE SURE EVERYTHING WORKED.
-
- ╫HILE MESSING AROUND IN DIFFERENT BANKS, TO BE SAFE ╔ DISSABLE ╔╥╤ INTERRUPTS.
- ╧N A RELATED NOTE, GEO─EBUGGER 2.0 SEEMS TO HAVE PROBLEMS WITH PROGRAMS
- MESSING AROUND WITH DIFFERENT BANKS. ╔T IS NOT SURPRISING THAT THE ┬ACK╥┴═
- DEBUGGER (WHICH LOCATES ITSELF IN ╥┴═ 0) WOULD HAVE TROUBLE WITH PROGRAMS THAT
- TRIED TO USE ╥┴═ 0, BUT IT ALSO HAS TROUBLE WITH PROGRAMS THAT TRY TO USE ╥┴═
- 2 AND 3. ╘HIS IS TRUE EVEN WHEN ONE USES THE SYSTEM ROUTINE ═OVE┬─ATA. (╔
- FOUND THAT ╔ WAS SOMETIMES ABLE TO MAKE IT PAST A CALL TO ═OVE┬─ATA WHILE IN
- THE DEBUGGER, BUT THAT MORE OFTEN THE SYSTEM WOULD HANG. ╘HIS IS ALL PROBABLY
- AN INTERRUPT-RELATED ISSUE.)
-
- ╔F ONE IS TO BE REALLY CLASSY, ONE DOESN'T ACTUALLY HAVE TO COPY THE ┌╨╩╙╥
- ROUTINE TO ZERO PAGE. ╧NE COULD ASSEMBLE THE APPLICATION SUCH THAT ┌╨╩╙╥ FELL
- TO A KNOWN OFFSET FROM A PAGE BOUNDRY; THEN, USE THE ══╒ TO POINT ZERO PAGE TO
- THE PAGE CONTAING ┌╨╩╙╥. ╒NFORTUNATELY, THIS TECHNIQUE DID NOT WORK ON MY
- 512╦ EXPANDED 128. ╘HE ONE INCOMPATILITY ╔ HAVE FOUND IS THAT WITH THE 512╦
- MODIFICATION ENABLED (╔ DO HAVE A SWITCH TO DISABLE IT, DON'T WORRY), THE ══╒
- FAILS TO CORRECTLY SEE ZERO PAGE IN ╥┴═ 1 WHEN REQUESTED TO. ╥ICHARD ├URCIO
- EXPERIMENTED WITH IT, AND IT SEEMS THAT WHEN YOU TRY TO RELOCATE ZERO PAGE TO
- A PAGE IN ╥┴═ 1, IT IS ACTUALLY SEEN IN ╥┴═ 3. ╔T IS NOT YET CLEAR WHETHER
- THIS IS A PROBLEM WITH THE 256╦/512╦ MODIFICATION, OR IF THE ══╒ IN A STOCK
- 128 JUST RELOCATES ┌╨ TO ╥┴═ 3 FIGURING THAT ╥┴═ 3 = ╥┴═ 1 (WHICH IS TRUE ON A
- STOCK 128, BUT NOT ON A 256╦ EXPANDED 128!)
-
-
-
- ┴NYONE WHO WANTS TO GET AHOLD OF THE ┬═OVER SOURCE, OR WHO HAS OTHER
- QUESTIONS/COMMENTS/FLAMES CAN CONTACT ME, ╥OBERT ╦NOP, AT THE FOLLOWING
- ADDRESSES:
-
- ╔NTER╬ET: RKNOP@TYBALT.CALTECH.EDU
- ╟┼NIE: ╥.╦╬╧╨1
- ╒.╙. ═AIL: ╥OBERT ╦NOP
- 123 ╙. ├HESTER #3
- ╨ASADENA, ├┴ 91106
-
-
- ╓. ╥EFERENCES
-
- [1] ╫ILLIAM ├OLEMAN, 1989: "╔NSIDE ╟┼╧╙ 128" _╘HE_╘RANSACTOR_ 9(4), P. 29.
-
- [2] ╥ICHARD ├URCIO, 1991: "┼XPANDING THE 128 ╨ART ╧NE: 256╦" _╘WIN_├ITIES_128_
- #30, P. 7.
-
- [3] ╥ICHARD ├URCIO, 1992: "┼XPANDING THE 128 ╨ART ╘WO: 4 ═ODE 512╦"
- _╘WIN_├ITIES_128_ #31, P. 5.
-
- [4] ┬ERKELEY ╙OFTWORKS, 1988: _╘HE_╚ITCHHIKER'S_╟UIDE_╘O_╟EOS_.
-
- [5] ═ICHAEL ╞ARR, 1987: _╘HE_╧FFICAL_╟┼╧╙_╨ROGRAMMER'S_╥EFERENCE_╟UIDE_.
- ┬ANTAM ┬OOKS, ╬EW ┘ORK/╘ORONTO.
-
- [6] ╠ARRY ╟REENLY ET. AL, 1986: _├OMMODORE_128_╨ROGRAMMER'S_╥EFERENCE_╟UIDE_.
- ┬ANTAM ┬OOKS, ╬EW ┘ORK/╘ORONTO.
-
- [7] ╧TTIS ╥. ├OWPER, 1986: _═APPING_THE_├OMMODORE_128_. ├OMPUTE! ╨UBLICATIONS,
- ╟REENSBORO, ╬├.
-
- ==============================================================================
- ─┘╬┴═╔├ ═┼═╧╥┘ ┴╠╠╧├┴╘╔╧╬ ╞╧╥ ╘╚┼ 128: ┬REAKING THE 64╦ ┬ARRIER
-
- BY ├RAIG ┬RUCE (F2RX@JUPITER.SUN.CSD.UNB.CA)
-
- ┴LTHOUGH THIS ARTICLE WOULD BE BEST DESCRIBED AS EXTREMELY TECHINICAL, ╔ THINK
- THAT IT HAS SOMETHING FOR EVERYONE. ╔T COULD ALSO BE DESCRIBED AS BEING
- EXTREMELY LONG.
-
- ┬ELOW ╔ HAVE WRITTEN A PROGRAM THAT WILL READ IN THE LINES OF A FILE, SORT
- THEM, AND WRITE THEN BACK OUT TO ANOTHER FILE. ┬ECAUSE OF THE NATURE OF THE
- PROBLEM, THE EACH LINE OF THE ENTIRE FILE MUST RESIDE IN THE MEMORY OF THE
- COMPUTER. ╔ IMPLEMENT AND USE DYNAMIC MEMORY ALLOCATION SUCH THAT THE FILE TO
- BE SORTED CAN BE LARGER THAN 64╦, AND ╔ USE A DYNAMIC DATA STRUCTURE SUCH THAT
- THE MEMORY IS USED VERY EFFICIENTLY. ╘HE MEMORY ROUTINES WERE EXTRACTED FROM
- A TEXT EDITOR CALLED "┌ED-128" WHICH ALSO BREAKS THE 64╦ BARRIER AND CAN EDIT
- SOME HUMONGOUS FILES (AND VERY EFFICIENTLY TOO). ┴LTHOUGH IMPLEMENTED FOR THE
- ├-128, THE DYNAMIC MEMORY SCHEME COULD ALSO BE FAIRLY EASILY (IE. IN A SINGLE
- LIFETIME) PORTED TO THE ├-64.
-
- ------------------------------------------------------------------------------
-
- 1. ╔╬╘╥╧─╒├╘╔╧╬
-
- ╚OW MANY OF US ARE SICK AND TIRED OF THE "64╦ LIMIT" THAT MANY PROGRAMS FOR
- THE 128 AND 64 SEEM TO HAVE? ═ANY TERMINAL PROGRAMS, TEXT EDITORS, AND EVEN
- FILE COPIERS SEEM TO BE AFFLICTED WITH THIS PROBLEM. ┴NOTHER PROBLEM IS THAT
- PROGRAMS OFTEN RESERVE LARGE SECTIONS OF MEMORY FOR SPECIFIC PURPOSES (SUCH AS
- THE KILL BUFFER OF A TEXT EDITOR) AND CANNOT RECONFIGURE THEMSELVES (VERY
- EASILY) FOR DIFFERENT DEMANDS. ╙TILL ANOTHER PROBLEM IS THAT MANY PROGRAMS DO
- NOT MAKE USE OF A ╥AM ┼XPANSION ╒NIT (IF YOU ARE FORTUNATE ENOUGH TO HAVE ONE)
- TO STORE YOUR VOLUMNOUS USER DATA.
-
- ╘HE WAY TO OVERCOME THE LIMITATIONS OF THE 64╦ ARCHITECTURE OF THE ├128 AND
- ├64 IS TO USE DYNAMICALLY ALLOCATED MEMORY. ╫HAT THIS MEANS IS THAT
- INITIALLY, ALL OF THE MEMORY OF THE COMPUTER IS FREE AND WHEN A USER PROGRAM
- REQUIRES SOME MEMORY TO STORE USER DATA, IT CALLS A SPECIAL SUBROUTINE THAT
- ALLOCATES A GIVEN NUMBER OF BYTES OF MEMORY TO THE PROGRAM TO STORE THE USER
- DATA. ┴ND WHEN THE PROGRAM IS FINISHED USING THAT CHUNK OF MEMORY, IT CALLS A
- SPECIAL SUBROUTINE TO FREE THE MEMORY CHUNK AND MAKE IT AVAILABLE FOR FUTURE
- ALLOCATE REQUESTS.
-
- ╧NE COMPLICATION OF THIS MEMORY USAGE SCHEME IS THAT A PROGRAM HAS TO KEEP
- TRACK OF WHICH CHUNKS OF MEMORY IT USES FOR WHAT. ╘HIS IS WHERE DYNAMIC DATA
- STRUCTURES COME IN. ╘HE MOST IMPORTANT CONCEPT HERE IS A POINTER. ┴ POINTER
- IS SIMPLY A VARIABLE THAT STORES THE ADDRESS OF SOME DATA STRUCTURE (IE. SOME
- CHUNK OF MEMORY). ╔F WE KNOW THE ADDRESS OF A DATA STRUCTURE, THEN WE CAN
- READ IT AND MODIFY IT.
-
- ╘O OVERCOME THE PROBLEM OF NOT KNOWING HOW MANY RECORDS WILL NEED TO BE
- STORED, RECORDS ARE OFTEN STORED IN LISTS, WHERE EVERY RECORD CONTAINS A
- POINTER TO THE NEXT RECORD IN THE LIST, EXCEPT FOR THE LAST ONE, WHICH
- CONTAINS A SPECIAL VALUE THAT COULD NOT BE MISTAKEN FOR AN ORDINARY POINTER
- (IT IS CALLED THE ╬ULL (OR ╬IL FOR YOU ╨ASCALERS) POINTER). ╘HUS, IF WE KNOW
- THE ADDRESS OF THE FIRST RECORD (BY USING A "HEAD POINTER"), THEN WE HAVE
- SEQUENTIAL ACCESS TO ALL OF THE RECORDS IN THE LIST. ╔F WE WANT TO ADD OR
- DELETE RECORDS FROM THE LIST, THEN WE MUST MODIFY THE OTHER POINTERS SUCH THAT
- THE CONSISTENCY OF THE LIST IS MAINTAINED. ╧RGANIZATIONS OTHER THAN SIMPLE
- LISTS ARE ALSO POSSIBLE.
-
- ╘HE IMPLEMENTATION HERE IS ABLE TO ALLOCATE ╥┴═0 MEMORY FOR STORING USER DATA
- RECORDS, AS WELL AS ╥┴═1 MEMORY AND EVEN ╥┼╒ MEMORY. ┴S LONG AS THE
- APPLICATION PROGRAM KEEPS TRACK OF THE POINTERS TO ITS RECORDS, LARGE VOLUMES
- OF USER DATA CAN BE STORED SINCE IT WILL BE DISTRIBUTED AMONG ALL OF THE
- MEMORY THAT IS AVAILABLE FROM BOTH THE INTERNAL MEMORY BANKS AND THE EXTERNAL
- MEMORY BANKS, THUS BREAKING THE 64╦ BARRIER.
-
- ------------------------------------------------------------------------------
-
- 2. ╞╧╥ ╘╚┼ ╬╧╓╔├┼ ╚┴├╦┼╥
-
- ┘OU GET A SORTING UTILITY PROGRAM. ╘HIS PROGRAM IMPLEMENTS THE INSERTION SORT
- ALGORITHM, SO DON'T EXPECT TO BREAK ANY SPEED RECORDS. ┴LSO, THE WAY THAT
- DYNAMIC MEMORY IS IMPLEMENTED HERE IS MORE SUITED FOR LARGE DATA STRUCTURES
- THAT WILL ONLY BE ACCESSED SLOWLY AND INFREQUENTLY (SUCH AS THE CURRENT
- DOCUMENT IN A TEXT EDITOR); HOWEVER, ╔ WANTED TO COME UP WITH A USEFUL UTILITY
- AND ╔ HAVE NEVER HEARD OF A GENERAL FILE SORTER FOR THE 128 OR 64. ╘HE
- INSERTION SORT DOES, HOWEVER, LEND ITSELF WELL TO BEING USED WITH DYNAMIC DATA
- STRUCTURES IN GENERAL, SINCE YOU DON'T ACTUALLY HAVE TO MOVE ANYTHING; YOU
- JUST CHANGE A COUPLE OF POINTERS IN ORDER TO INSERT A LINE (RECORD) BETWEEN
- TWO OTHER LINES. ┴LSO, IT TURNS OUT THE THE INSERTION SORT IS QUITE EFFICIENT
- IF YOUR INPUT FILE IS ALREADY MOSTLY OR PARTIALLY SORTED.
-
- ╘HE SORT UTILITY ITSELF IS COMPLETELY MACHINE LANGUAGE BUT ASSUMES THAT THE
- INPUT AND OUTPUT FILES ARE ALREADY OPENED, SO A ┬┴╙╔├ DRIVER PROGRAM IS
- REQUIRED TO SET THINGS UP TO AND ALLOW THE USER TO EASILY CHANGE THE SORTING
- PARAMETERS. ╙UCH A PROGRAM IS LISTED HERE:
-
- 1 I$="INPUTFILE.TXT" : ID=8 : SF=1
- 2 O$="OUTPUTFILE.TXT" : OD=8
- 3 :
- 100 PRINT"LOADING SORT.BIN..."
- 110 BANK 15
- 120 BLOAD"SORT.BIN",U(ID)
- 130 PRINT"SCRATCHING OLD FILE..."
- 140 SCRATCH(O$),U(OD)
- 150 PRINT"SORTING..."
- 160 OPEN1,ID,2,"0:"+I$
- 170 OPEN2,OD,3,"0:"+O$+",S,W"
- 180 SYS DEC("1300"),SF
- 190 CLOSE2
- 200 CLOSE1
- 210 PRINT"FINISHED!"
-
- ╠INES 1 AND 2 SET UP THE SORTING PARAMETERS: THE INPUT AND OUTPUT FILENAMES,
- THE INPUT AND OUTPUT FILE DEVICE NUMBERS, AND THE SORTING FIELD POSITION.
- ├HANGE THE "SF" VALUE TO THE POSITION OF THE FIRST CHARACTER OF THE KEY
- FIELD. ╘HE FIRST POSITION ON THE LINE IS 1 (NOT 0). (╘HIS CORRESPONDS TO
- WHAT ┌ED USES FOR COLUMNS). ╙TARTING FROM THAT POSITION, THE REST OF THE LINE
- IS USED FOR THE COMPARISON THAT DETERMINES THE ORDER OF THE LINES. ╔F A LINE
- IS ENCOUNTERED THAT IS SHORTER THAN THE POSITION OF THE SORTING FIELD, THE KEY
- VALUE IS TAKEN TO BE THE ╬ULL ╙TRING (WHICH COMES BEFORE ANY OTHER STRING).
-
- ╘HE PROGRAM CONTINUES TO LOAD IN THE MACHINE LANGUAGE (WHICH FITS INTO THE
- $1300 SLOT) AND SCRATCH THE OUTPUT FILE IF IT ALREADY EXISTS. ╘HEN THE FILES
- ARE OPENED, MACHINE LANGUAGE IS CALLED, AND THE FILES ARE CLOSED AND THE
- PROGRAM EXITS. ╫HILE READING THE FILE, THE PROGRAM WILL SPLIT ANY LINES THAT
- ARE LONGER THAN 242 CHARACTERS AND TREAT THEM AS MULTIPLE LINES.
-
- ╞OR TESTED THE SORT UTILITY, ╔ USED A FILE THAT CONTAINS 1058 LINES OF THE
- FOLLOWING FORM:
-
- ╥╧╪┼╘╘┼ ═╒╙╘ ╚┴╓┼ ┬┼┼╬ ╠╧╓┼ ┴01-1-01
- ┴─┴═╙, ┬╥┘┴╬ ╙╒══┼╥ ╧╞ '69 ┴05-1-10
- ╩╧┼╠, ┬╔╠╠┘ ╨╥┼╙╙╒╥┼ ═11-1-07
- ┼┴╟╠┼╙ ╬┼╫ ╦╔─ ╔╬ ╘╧╫╬ ╥06-2-04
- ┼╠┼├╘╥╔├ ╠╔╟╚╘ ╧╥├╚┼╙╘╥┴ ├┴╠╠╔╬╟ ┴═┼╥╔├┴ ╥11-1-05
- ├╧├╦┬╒╥╬, ┬╥╒├┼ ╫╧╬─┼╥╔╬╟ ╫╚┼╥┼ ╘╚┼ ╠╔╧╬╙ ┴╥┼ ╥14-1-03
-
- ┴S YOU MAY GUESS, IT IS A TAPE LIBRARY. ╘HE FILE IS 83╦ IN LENGTH. ╔ SORTED
- IT ON BOTH MY 1581 (WITH ╩IFFY─╧╙) AND MY ╥AM╠INK AND THEN ╔ SORTED AGAIN THE
- FILE THAT ╔ SORTED IN THE FIRST PLACE. ╘HE RESULTING EXECUTION TIMES ARE AS
- FOLLOWS:
-
- ╫╔╘╚ ┼╪╨┴╬╙╔╧╬ ═┼═╧╥┘ ╫╔╘╚╧╒╘ ┼╪╨┴╬╙╔╧╬ ═┼═╧╥┘
-
- ╥AMLINK REGULAR = 110 SECONDS ╥AMLINK REGULAR = 376 SECONDS
- ╥AMLINK SORTED = 20 SECONDS ╥AMLINK SORTED = 24 SECONDS
- 1581 REGULAR = 120 SECONDS 1581 REGULAR = 397 SECONDS
- 1581 SORTED = 33 SECONDS 1581 SORTED = 55 SECONDS
-
- ┘OU'LL NOTE THAT HAVING EXPANSION MEMORY MAKES SORT OPERATE FASTER. ╘HIS IS
- BECAUSE THE ╥┼╒ ├ONTROLLER CAN TRANSFER DATA AROUND FASTER THAN THE ├╨╒ CAN.
- ╘HE EFFECT IS EVEN MORE PRONOUNCED WHEN USING RECORDS LONGER THAN 78-CHARACTER
- LINES OF TEXT. ╘HIS IS WHY IT IS SENSIBLE TO USE EXPANSION MEMORY FOR GENERAL
- DATA STORAGE AND ACCESSING. ╘HE REASON WHY THE EXECUTION TIMES ARE SO LONG IS
- THAT APPROXIMATELY 1058*529/2 = 280,000 "FAR MEMORY" LINE-LENGTH FETCHES HAVE
- TO TAKE PLACE, ALONG WITH THAT NUMBER OF "ZPLOAD"S AND STRING COMPARISONS, AND
- 1058 "MALLOC"S AND "FREE"S. ┴LSO, WE ALL KNOW THAT THE ├OMMODORE FILE READING
- AND WRITING MECHANISMS ARE NOT SEVERELY SWIFT.
-
- ------------------------------------------------------------------------------
-
- 3. ╞╧╥ ╘╚┼ ╔╬╘┼╥═┼─╔┴╘┼ ╚┴├╦┼╥
-
- ┘OU GET A DYNAMIC MEMORY ALLOCATION AND USAGE PACKAGE THAT CAN BE INCORPORATED
- INTO YOUR OWN PROGRAMS.
-
- 3.1. ═┼═╧╥┘ ╨┴├╦┴╟┼ ├┴╠╠╙
-
- ╘HE PACKAGE INCLUDES EIGHT SYSTEM CALLS:
-
- STARTUP ()
- SHUTDOWN()
- ZPLOAD ( [ZP1]=╞AR╨OINTER, .╪=┌P┴DDR, .┘=╠ENGTH )
- ZPSTORE ( [ZP1]=╞AR╨OINTER, .╪=┌P┴DDR, .┘=╠ENGTH )
- FETCH ( [ZP1]=╞AR╨OINTER, (ZW1)=╥AM0POINTER, .┴┘=╠ENGTH )
- STASH ( [ZP1]=╞AR╨OINTER, (ZW1)=╥AM0POINTER, .┴┘=╠ENGTH )
- MALLOC ( .┴┘=╠ENGTH ) : [ZP1]=╞AR╨OINTER, .├╙=ERROR
- FREE ( [ZP1]=╞AR╨OINTER, .┴┘=╠ENGTH ) : .├╙=ERROR
-
- ╘HE "(...)" MEANS INPUT PARAMETERS AND ":" PRECEEDS OUTPUT PARAMETERS. ".╪"
- AND ".┘" REFER TO THE PROCESSOR REGISTERS AND ".┴┘" MEANS THE 16-BIT VALUE
- WITH THE .┴ REGISTER HOLDING THE LOW BYTE AND THE .┘ REGISTER HOLDING THE HIGH
- BYTE. ╫ITH "(ZW1)" ╔ AM REFERING TO THE INDIRECT POINTER IN THE ZERO PAGE
- LOCATIONS "ZW1" (LOW BYTE) AND "ZW1+1" (HIGH BYTE) ("ZW" MEANS ZERO PAGE WORD
- AND IT IS ASSIGNED TO LOCATIONS $╞┼ TO $╞╞) AND WITH "[ZP1]" ╔ AM REFERING TO
- THE THREE BYTE POINTER VALUE IN LOCATIONS "ZP1" (ADDRESS LOW BYTE), "ZP1+1"
- (ADDRESS HIGH BYTE), AND "ZP1+2" (BANK NUMBER BYTE) ("ZP" MEANS ZERO PAGE
- POINTER AND IT IS ASSIGNED TO ADDRESSES $╞┴ TO $╞├). ╘HIS THREE-BYTE POINTER
- IS REFERED TO AS A "╞AR ╨OINTER". ╘HE ".├╙=ERROR" MEANS THAT IF THE ROUTINE
- RETURNS WITH THE CARRY FLAG SET, AN ERROR HAS OCCURED. ╘HE ONLY POSSIBLE
- ERROR RETURN IN THIS PACKAGE IS IF MALLOC CANNOT FIND ENOUGH CONTIGUOUS FREE
- MEMORY TO SATISFY YOUR REQUEST.
-
- ┘OU DO NOT ACTUALLY HAVE TO KNOW WHAT THE BANK NUMBERS MEAN SINCE THEY ARE
- GENERATED AND USED BY THE PACKAGE AS AN OPAQUE DATA TYPE (PARLEZ-VOUS
- ═ODULA-2?), BUT HERE IS WHAT THEY MEAN ANYWAY. ┴ VALUE OF $3╞ MEANS INTERNAL
- BANK ╥┴═0 AND A VALUE OF $7╞ MEANS INTERNAL BANK ╥┴═1. ╘HIS WORKS OUT
- CONVENIENTLY IN THE IMPLEMENTATION, SINCE THESE ARE THE ══╒ CONFIGURATION
- REGISTER VALUES FOR THOSE TWO BANKS. ┴ VALUE FROM $80 TO $╞┼ REFERS TO AN
- EXPANSION (╥┼╒) MEMORY BANK. $80 MEANS EXPANSION BANK0, $81 BANK1, ETC. ╘HIS
- MEANS THAT THE PACKAGE CAN SUPPORT UP TO 8 ═EGS (MINUS 64╦) OF EXPANSION
- MEMORY (AND IT DOES). ╘HESE VALUES ARE CONVENIENT TO USE SINCE AFTER LOADING
- THE BANK NUMBER INTO A REGISTER, THE ╬EGATIVE FLAG OF THE PROCESSOR WILL BE
- SET (USEFUL IF HANDLING EXPANSION MEMORY IS A SPECIAL CASE), AND THIS VALUE
- CAN BE PUT DIRECTLY INTO THE ╥┼╒ ├ONTROLLER'S BANK REGISTER. ╔ DON'T THINK
- YOU HAVE TO WORRY ABOUT HAVING THE HIGH BIT BE A "1" SINCE IT IS DONE
- CONSISTENTLY AND ╔ HAVE NEVER HEARD OF AN ╥┼╒ LARGER THAN 2 ═EGS. ┴ BANK
- VALUE OF $╞╞ IS USED TO REPRESENT THE ╬ULL POINTER.
-
- ╘HE "STARTUP" ROUTINE INSTALLS THE COMMON CODE, DETERMINES THE SIZE OF YOUR
- ╥┼╒, AND INITIALIZES THE DYNAMIC MEMORY ALLOCATION MECHANISM. ╔N ORDER FOR
- THE PACKAGE TO ACCESS INTERNAL MEMORY BANK ╥┴═1, IT HAS TO CALL A ROUTINE THAT
- IS IN MEMORY BELOW ADDRESS $0400. ╙INCE THE PACKAGE STARTS AT $1300, IT HAS
- TO COPY A FEW "COMMON CODE" SUBROUTINES INTO LOW MEMORY SUCH THAT IT CAN CALL
- THEM LATER. ╘HE COMMON CODE IS INSTALLED AT ADDRESS $0200, THE ┬┴╙╔├ INPUT
- BUFFER. ─ON'T OVERWRITE THIS AREA WHILE THE PACKAGE IS IN USE. ╘HE "SNIFF"
- ROUTINE IS CALLED TO DETERMINE THE NUMBER OF BANKS THAT YOUR ╥┼╒ HAS. ┌ERO
- BANKS MEANS THAT YOU HAVE NO ╥┼╒. ╫HILE SNIFFING, THE PACKAGE OVERWRITES THE
- FIRST FOUR BYTES OF EVERY EXISTING EXPANSION BANK (UNLESS YOU LIMIT THE NUMBER
- OF EXPANSION BANKS THAT THE PACKAGE IS ALLOWED TO USE). ╘O INITIALIZE THE
- DYNAMIC MEMORY ALLOCATION, THE "FREE" ROUTINE IS CALLED FOR ╥┴═0, ╥┴═1, AND
- EACH EXPANSION BANK. ╥┴═0 FROM $4000 TO THE TOP OF ┬┴╙╔├ MEMORY ($╞┼╞╞) IS
- FREED, ╥┴═1 FROM $0400 TO $╞┼╞╞ IS FREED, AND ALL EXPANSION BANKS ARE FREED
- BETWEEN ADDRESSES $0000 TO $╞╞╞7. ╘HUS, IF YOU HAVE NO EXPANSION MEMORY, YOU
- GET ABOUT 110╦ FREE AND IF YOU HAVE A 512╦ EXPANDER, YOU GET ABOUT 620╦ FREE.
-
- ╘HE "SHUTDOWN" ROUTINE DOESN'T ACTUALLY HAVE VERY MUCH TO DO. ┬ASICALLY, IT
- JUST ZEROS OUT THE COMMON CODE. ╔ DID THIS SO IF YOU CALLED THE SORT ROUTINE
- FROM ┬┴╙╔├ DIRECT INPUT MODE, YOU WOULD NOT GET A "SYNTAX ERROR" FROM ┬┴╙╔├
- TRYING TO INTERPRET THE GARBAGE LEFT BEHIND. ╬OW, WHEN ┬┴╙╔├ ENCOUNTERS A
- ZERO, IT STOPS INTERPRETING.
-
- ╘HE "ZPLOAD" ROUTINE WILL LOAD THE GIVEN NUMBER OF BYTES INTO ZERO PAGE
- STARTING AT THE GIVEN ZERO PAGE ADDRESS, FROM ANY FAR POINTER ADDRESS. ╔T
- DOESN'T MATTER WHETHER THE FAR ADDRESS IS IN INTERNAL OR EXPANSION MEMORY; THE
- OPERATION IS THE SAME. ╘HIS IS THE LEVEL OF SOFTWARE THAT MAKES ACCESSING THE
- DIFFERENT TYPES OF MEMORY TRANSPARENT TO THE USER. ╘O LOAD FROM ╥┴═0, TRUE
- ╥┴═0 IS SWITCHED INTO CONTEXT (DID ╔ MENTION THAT THE PACKAGE IS MEANT TO
- EXECUTE WITH ══╒ CONFIGURATION $0┼ IN CONTEXT - THIS CONFIGURATION GIVES ╥┴═0
- FROM $0000 TO $┬╞╞╞, THE KERNEL ╥╧═ FROM $├000 TO $╞╞╞╞ AND THE ╔/╧ SPACE ON
- TOP OF THE KERNEL ╥╧═ FROM $─000 TO $─╞╞╞ - ╔ CALL THIS THE ╙┘╙ OR ╙┘╙0 BANK)
- AND THE TRANSFER IS DONE WITH A LOOP. ╞OR A ZPLOAD FROM ╥┴═1, A COMMON CODE
- ROUTINE IS CALLED THAT SWITCHES ╥┴═1 INTO CONTEXT, COPIES IN A LOOP, AND THEN
- SWITCHES BACK TO ╙┘╙0. ╞OR AN EXPANSION MEMORY POINTER, THE ╥┼╒ ├ONTROLLER
- REGISTERS ARE SET UP AND THE TRANSFER IS PERFORMED. ╘HE PACKAGE WILL WORK
- WITH WHATEVER ┌ERO ╨AGE IS IN CONTEXT (WITH ══╒ REGISTER $─507), SINCE IT IS
- CONVENIENT TO USE YOUR OWN ZERO PAGE IN YOUR PROGRAMS. ╞OR TRANSFERS OF LESS
- THAN ABOUT 16 BYTES, INTERNAL MEMORY IS FASTER, AND FOR LONGER TRANSFERS,
- EXPANSION MEMORY TURNS OUT TO BE FASTER. ╞OR REALLY LONG TRANSFERS (SAY, 80
- BYTES), USING THE EXPANSION MEMORY IS ═╒├╚ FASTER (A MARGINAL COST OF ONE
- MICROSECOND PER BYTE AS OPPOSED TO NINE). ╘HE "[ZP1]" PARAMETER IS UNALTERED
- BY THIS CALL, BUT THE REGISTER VALUES ARE QUITE CHANGED. ╘HE "(ZW1)"
- PARAMETER AREA IS ALSO LEFT UNTOUCHED.
-
- ╘HE "ZPSTORE" ROUTINE WORKS THE SAME AS "ZPLOAD" EXCEPT IT STORES TO THE FAR
- MEMORY FROM ZERO PAGE.
-
- ╘HE "FETCH" ROUTINE FETCHES THE GIVEN NUMBER OF BYTES FROM A FAR ADDRESS INTO
- THE ╥┴═0 BANK (NOT ╙┘╙0) AT THE GIVEN ADDRESS. ╒NLIKE THE ZERO PAGE LOAD
- ROUTINE, YOU CAN TRANSFER UP TO 64╦ OF MEMORY WITH THIS ROUTINE. ┴GAIN, THE
- TYPE OF MEMORY TO BE FETCHED IS TRANSPARENT TO THE USER. ╞OR AN INTERNAL
- MEMORY FETCH, THE TRANSFERS ARE PERFORMED IN 256 BYTE CHUNKS. ╘HIS MAKES THE
- IMPLEMENTATION EASIER. ╞OR EACH BYTE TRANSFERRED FROM ╥┴═1, ╥┴═1 IS SWITCHED
- IN AND THEN ╥┴═0 IS SWITCHED IN, SO THE TRANSFER IS NOT EXTREMELY EFFICIENT.
- ╞OR THE EXPANSION MEMORY, THE ╥┼╒ ├ONTROLLER IS SET UP AND THEN THE ENTIRE
- TRANSFER (UP TO 64╦) IS PERFORMED AT A RATE OF 1 ═EG/SECOND. ╘HIS IS
- CONSIDERABLY FASTER THAN INTERNAL MEMORY FETCHING. ╘HIS ROUTINE HANDLES A
- TRANSFER LENGTH OF 0 BYTES PROPERLY. ╘HE "ZP1" AND "ZW1" PARAMETERS ARE
- RETURNED UNALTERED, BUT AGAIN, THE REGISTERS ARE SMASHED.
-
- ╘HE "STASH" ROUTINE OPERATES THE SAME AS FETCH, EXCEPT THAT THE DATA IS
- TRANSFERRED FROM THE NEAR ("ZW1") ADDRESS TO THE FAR ("ZP1") ADDRESS.
-
- ╘HE "MALLOC" ROUTINE ATTEMPTS TO FIND A CHUNK OF CONTIGUOUS MEMORY OF THE
- GIVEN LENGTH TO ALLOCATE TO YOU. ╔F IT CAN FIND ONE, IT RETURNS THE FAR
- POINTER TO IT IN THE "[ZP1]" PARAMETER. ╔F IT CANNOT FIND ONE, IT RETURNS
- WITH THE CARRY FLAG SET. ╘HIS ROUTINE CLOBBERS THE REGISTERS.
-
- ╘HE "FREE" ROUTINE RETURNS TO THE POOL OF FREE MEMORY THE CHUNK OF MEMORY
- SPECIFIED BY THE FAR POINTER AND LENGTH PARAMETERS. ╘HIS ROUTINE CLOBBERS THE
- "[ZP1]" PARAMETER AND THE REGISTERS. ╘HE CARRY FLAG IS ALWAYS CLEARED UPON
- RETURN, SINCE THE ROUTINE DOES NOT (CURRENTLY) CHECK FOR ANY ERRORS.
-
- 3.2. ═┼═╧╥┘ ┴╠╠╧├┴╘┼ ┴╬─ ╞╥┼┼
-
- ╘HE MALLOC AND FREE ROUTINES MAINTAIN A LINKED LIST OF FREE MEMORY CHUNKS. ┴
- FREE MEMORY CHUNK IS DESCRIBED BY A FIVE BYTE STRUCTURE THAT IS AT THE
- BEGINNING OF THE CHUNK. ╘HE FIRST THREE BYTES ARE A FAR POINTER TO THE NEXT
- FREE MEMORY CHUNK AND THE FOLLOWING TWO BYTES GIVE THE TOTAL LENGTH OF THE
- CHUNK. ╘HE STRUCTURE IS THUS:
-
- +----------+----------+----------+----------+----------+---...
- ▄ ╬EXT ▄ ╬EXT ▄ ╬EXT ▄ ├HUNK ▄ ├HUNK ▄
- ▄ CHUNK ▄ CHUNK ▄ CHUNK ▄ LENGTH ▄ LENGTH ▄ GARBAGE
- ▄ LOW ADDR ▄ HIGH ADDR▄ BANK NUM ▄ LOW ▄ HIGH ▄
- +----------+----------+----------+----------+----------+---...
- CHUNK+0 CHUNK+1 CHUNK+2 CHUNK+3 CHUNK+4
-
- ┴LL OF THE FREE (AND ALLOCATED) MEMORY CHUNKS ARE ALWAYS ALIGNED ON AN EIGHT
- BYTE BOUNDARY. ╘HIS GUARANTEES THAT NO MATTER WHAT HAPPENS, THERE WILL ALWAYS
- BE AT LEAST EIGHT BYTES AVAILABLE IN EACH FREE MEMORY CHUNK TO HOLD THE FREE
- CHUNK DESCRIPTOR INFORMATION. ╘HUS, IF YOU WERE TO MAKE A REQUEST FOR THREE
- BYTES, THE SYSTEM WOULD GIVE YOU EIGHT, AND WHEN YOU REQUEST TO FREE THOSE
- THREE BYTES, THE SYSTEM WOULD AUTOMATICALLY FREE EIGHT. ╘HIS CAN LEAD TO SOME
- SOME WASTED SPACE WHEN USING SMALL STRUCTURES.
-
- ╘HE MEMORY CHUNKS ARE KEPT IN ORDER OF "INCREASING" ADDRESS. ╔ SAY
- "INCREASING" BECAUSE WHILE THE CHUNKS WITHIN A BANK ARE IN INCREASING ADDRESS
- ORDER, THE SYSTEM CONSIDERS BANK NUMBER $87 (EXPANSION BANK 7) TO BE LOWER
- THAN BANK NUMBER $3╞ (╥┴═0). ╘HIS ANOMOLY MAKES THE SYSTEM ALLOCATE ITS
- EXTERNAL MEMORY BEFORE ALLOCATING INTERNAL MEMORY. ╘HIS IS GOOD SINCE
- EXTERNAL MEMORY GENERALLY WORKS FASTER THAN INTERNAL MEMORY.
-
- ╘HIS MEMORY IS ALLOCATED FIRST SINCE THE MALLOC ROUTINE USES A FIRST-FIND
- ALGORITHM FOR SEARCHING FOR A SUFFICIENT FREE MEMORY CHUNK. ╔T STOPS
- SEARCHING WHEN IT FINDS A FREE MEMORY CHUNK LARGE ENOUGH TO SATISFY THE USER'S
- REQUEST. ╔F THE FREE CHUNK IS EXACTLY THE SAME SIZE AS THE REQUEST, THE FREE
- CHUNK IS UNLINKED FROM THE FREE CHUNK LIST AND THE POINTER IS RETURNED. ╔F
- THE FREE CHUNK IS LARGER THAN THE REQUESTED SIZE, IT IS SPLIT UP. ┴ POINTER
- TO THE TOP ╬ BYTES OF THE CHUNK IS RETURED TO THE USER AND THE SIZE OF THE
- FREE CHUNK IS REDUCED BY ╬. ╘HE MEMORY IS ALLOCATED FROM THE TOP OF THE CHUNK
- MAKE IT SO NO LINKING AND UNLINKING HAS TO TAKE PLACE IN THIS CASE.
-
- ╘HE FREE ROUTINE IS MORE COMPLICATED THAN THE ALLOCATE ROUTINE SINCE FREE HAS
- TO DEAL WITH MORE CASES. ╞REE HAS TO SEARCH THROUGH THE LINKED LIST OF FREE
- MEMORY CHUNKS TO FIND THE TWO CHUNKS THAT STRADDLE THE CHUNK TO BE FREED.
- ╞REE ATTEMPTS TO COALESCE (MERGE) THE NEW CHUNK WITH THE PREVIOUS CHUNK AND
- WITH THE NEXT CHUNK IN ORDER TO END UP WITH THE LARGEST FREE CHUNKS THAT IT
- CAN UNDER THE CIRCUMSTANCES. ╠ARGE FREE CHUNKS ARE GOOD SINCE THEY CAN BE
- USED FOR LARGER REQUESTS. ╘WO CHUNKS CAN BE COALESCED IF THEY ARE
- SIDE-BY-SIDE IN MEMORY (ZERO BYTES APART) AND ON THE SAME BANK. ╘O COALESCE
- THEM, THE SIZE OF THE FIRST ONE IS INCREASED BY THE SIZE OF THE SECOND ONE AND
- THE POINTER TO THE SECOND ONE IS FORGOTTEN.
-
- ╬OTE THAT THIS SCHEME WORKS DIFFERENTLY FROM THE DYNAMIC ALLOCATION SCHEME
- THAT ┬┴╙╔├ USES FOR ITS STRINGS. ┬┴╙╔├ DOES NOT ATTEMPT TO COALESCE TOGETHER
- (OR EVEN RE-USE) FREED CHUNKS; IT RELIES UPON GARBAGE COLLECTING TO GET RID OF
- THE FREE CHUNKS. ╘HE SCHEME IMPLEMENTED HERE IS MORE STATIC (INTERESTING WORD
- TO CHOOSE) IN THAT ONCE YOU ARE ALLOCATED A CHUNK, THAT CHUNK IS PINNED TO
- THAT ADDRESS AND WILL NEVER MOVE. ╘HIS STATIC ORGANIZATION CAN LEAD TO THE
- PROBLEM OF MEMORY FRAGMENTATION, WHERE LOTS OF MEMORY CAN BE FREE BUT IS IN
- UN-COALESCABLE CHUNKS THAT ARE TOO SMALL TO BE USEFUL. ╧H WELL. ╔ DON'T
- THINK THAT IT IS REALLY A PROBLEM FOR STORING LINES OF TEXT AS INDIVIDUAL
- RECORDS, AND IT IS NO PROBLEM AT ALL FOR A PROGRAM THAT ALWAYS USES FIXED SIZE
- RECORDS.
-
- 3.3. ╘╚┼ ╙╧╥╘ ╒╘╔╠╔╘┘
-
- ╘HE WAY THAT THE SORT UTILITY MAKES FULL USE OF THE CAPABILITES OF THE
- PACKAGE. ╞IRST IT READS IN THE INPUT FILE ONE LINE AT A TIME AND STORES THE
- LINES IN A LINKED LIST AS INDIVIDUAL RECORDS OF THE FORM:
-
- +--------+--------+--------+--------+-------...-----+--------+
- ▄ ╬EXT ▄ ╬EXT ▄ ╬EXT ▄ ╘OTAL ▄ ▄ ▄
- ▄ LINE ▄ LINE ▄ LINE ▄ RECORD ▄ CHARACTERS ▄ .BYTE ▄
- ▄ PTR ▄ PTR ▄ PTR ▄ LENGTH ▄ OF THE LINE ▄ $00 ▄
- ▄ LOW ▄ HIGH ▄ BANK ▄ ▄ ▄ ▄
- +--------+--------+--------+--------+-------...-----+--------+
- LINE+0 LINE+1 LINE+2 LINE+3 LINE+4 LINE+?
-
- ╬OTE THAT THESE ARE VARIABLE LENGTH RECORDS; EACH RECORD IS ONLY AS LONG AS IT
- HAS TO BE. ╘HE TOTAL RECORD LENGTH IS STORED AT THE FRONT OF THE RECORD. ╔N
- ORDER TO READ A LINE INTO A PROCESSING BUFFER, A "ZPLOAD" IS DONE THAT READS
- THE FIRST FOUR BYTES OF THE RECORD IN ORDER TO GET THE LENGTH OF THE RECORD.
- ╘HEN THE ENTIRE RECORD CAN BE FETCHED SINCE ITS LENGTH IS KNOWN AT THAT TIME.
- ┼ACH RECORD ENDS WITH A $00 BYTE TO SIMPLIFY THE STRING COMPARISON
- SUBROUTINE.
-
- ╘HE LINE LIST IS MAINTAINED IN ALPHABETICAL ORDER (ACTUALLY, REVERSE
- ALPHABETICAL ORDER; BELOW). ╫HEN A NEW LINE IS READ IN FROM THE INPUT FILE,
- THE LINE LIST IS SEARCHED FOR THE TWO OTHER LINES WHOSE VALUES STRADDLE THE
- VALUE OF THE NEW LINE. ╘HE LINE IS THEN LINKED IN AT THAT POSITION IN THE
- LIST. ╬O OTHER LINES HAVE TO BE MOVED AROUND SINCE POINTERS ARE USED TO
- MAINTAIN THE ORDER OF THE LIST. ╔N ORDER FOR A LINE ALREADY IN THE LIST TO BE
- COMPARED WITH THE NEW LINE, THE OLD LINE HAS TO BE FETCHED FROM FAR MEMORY
- (USING THE ZPLOAD + FETCH SCHEME ABOVE) INTO A WORK BUFFER IN THE ╙┘╙0 BANK.
- ╧N AVERAGE, HALF OF THE EXISTING LIST WILL HAVE TO BE SEARCHED IN THIS WAY IN
- ORDER TO FIND THE CORRECT SPOT TO INSERT THE NEW LINE.
-
- ┴FTER THE POSITION FOR THE NEW LINE IS FOUND, SPACE FOR THE LINE IS ALLOCATED
- BY CALLING "MALLOC" AND THEN THE DATA IS STORED FROM THE WORK BUFFER IT WAS
- READ INTO TO FAR MEMORY. ╘HE ZPLOAD AND ZPSTORE ROUTINES ARE USED TO MODIFY
- THE POINTERS TO LINK IN THE NEW LINE. ┴ NUMBER OF POINTER MANIPULATIONS ARE
- ALSO REQUIRED ON THE ZERO PAGE VARIALBLES.
-
- ╔F THE LINE LIST WAS GENERATED IN FORWARD ALPHABETIC ORDER, THEN THE UTILITY
- WOULD ACHIEVE ITS ╫╧╥╙╘ PERFORMANCE WHEN THE INPUT FILE WAS ALREADY MOSTLY OR
- PARTIALLY SORTED. ╘HIS IS BECAUSE WHEN EACH LINE IS READ, IF IT COMES AFTER
- MOST OR ALL OF THE OTHER LINES, THE MOST OR ALL OF THE LINE LIST WOULD HAVE TO
- BE SEARCHED TO FIND THE FINAL RESTING POSITION FOR THE NEW LINE. ╘HIS WOULD
- BE UNACCEPTABLE AND EXTREMELY WASTEFUL. ┴ BETTER SCHEME IS TO GENERATE THE
- LINE LIST IN REVERSE ALPHABETIC ORDER. ╘HEN, WHEN A "HIGHER VALUED" LINE IS
- READ IN, ITS CORRECT POSITION WOULD BE AT OR NEAR THE TOP OF THE LIST, SO ONLY
- IT WOULD ONLY HAVE TO BE COMPARED AGAINST A FEW OF THE LINES ALREADY ON THE
- LIST. ╔N THE CASE OF AN INPUT FILE THAT IS ALREADY IN PRETTY MUCH RANDOM
- ORDER, IT MAKES NO DIFFERENCE WHETHER THE LIST IS IN FORWARD OR REVERSE
- ORDER.
-
- ╙INCE THE LIST IS GENERATED IN REVERSE ORDER, IT MUST BE REVERESED AGAIN
- BEFORE WRITING IT TO THE OUTPUT FILE, SINCE THE USER WOULD WANT IT TO BE IN
- FORWARD ORDER (AND SINCE THIS IS THE ORDER THAT CAN BE MOST EASILY SORTED
- AGAIN LATER). ┴ CLEVER LITTLE SUBROUTINE IS CALLED THAT REVERSES THE ORDER OF
- THE LIST. ╔T ONLY HAS TO MAKE USE OF ZPLOAD AND ZPSTORE TO READ/CHANGE THE
- FIRST FEW BYTES OF EACH RECORD, SINCE IT IS NOT CONCERNED WITH THE DATA
- CONTENTS OF EACH RECORD.
-
- ┴LTHOUGH THIS IS NOT STRICTLY NECESSARY, ALL OF THE RECORDS IN THE LINE LIST
- ARE FREED BEFORE THE SORT UTILITIY EXITS. ╘HIS IS A GOOD PRACTICE, AND WOULD
- NECESSARY IF THE PROGRAM WERE TO CONTINUE TO DO USEFUL WORK AFTER WRITING THE
- SORTED FILE TO OUTPUT. ┴ POINTER IS STEPPED THROUGH THE LIST (STARTING FROM
- THE HEAD POINTER) AND THE SPACE FOR EACH LINE IS DEALLOCATED BY CALLING FREE,
- AFTER DETERMINING THE SIZE OF THE RECORD BY READING THE FIRST FEW BYTES OF
- IT. ╙INCE THE LIST WILL BE IN (PRETTY MUCH) RANDOM ORDER (OF ADDRESSES), THE
- DEALLOCATION MECHANISM DOES NOT ACHIEVE ITS BEST PERFORMANCE.
-
- ┴ CONVENIENT JUMP TABLE IS SET UP AT THE START OF THE CODE TO MAKE IT EASIER
- FOR YOU TO LINK YOUR OWN PROGRAMS TO THE PACKAGE. ═AKE SURE THAT ══╒
- CONFIGURATION VALUE $0┼ IS IN EFFECT BEFORE CALLING ANY OF THE ROUTINES. ┘OU
- MAY HAVE TO MUCK WITH THE CODE A LITTLE BIT TO GET IT TO WORK FOR YOU.
-
- ------------------------------------------------------------------------------
-
- 4. ╞╧╥ ╘╚┼ ┼╪╨┼╥╘ ╚┴├╦┼╥
-
- ┘OU GET TO SEE THE CODE THAT ACTUALLY IMPLEMENTS THE MEMORY PACKAGE AND THE
- SORT UTILITY. ╔ HAVE IT HERE IN A SPECIAL FORM; EACH CODE LINE IS PRECEEDED
- BY A FEW SPECIAL CHARACTERS AND THE LINE NUMBER. ╘HE LINE NUMBER IS THERE TO
- ALLOW ME TO REFER TO SPECIFIC LINES, AND THE SPECIAL CHARACTERS ARE THERE TO
- ALLOW YOU TO EASILY EXTRACT THE ASSEMBLER CODE FROM THE REST OF THIS MAGAZINE
- (AND ALL OF MY UGLY COMMENTS). ╧N A ╒NIX SYSTEM, ALL YOU HAVE TO DO IS
- EXECUTE THE FOLLOWING COMMAND LINE (SUBSTITUTE FILENAMES AS APPROPRIATE):
-
- GREP '^\.%....\!' ╚ACK2 ▄ SED 'S/^.%....\!..//' ▄ SED 'S/.%....\!//' >SORT.ASM
-
- ─ONTCHA JUST LOVE THOSE ╒NIX COMMANDS! ╚ERE IS THE ASSEMBLER CODE:
-
- .%0001! ;╙ORT UTILITY USING DYNAMIC MEMORY ALLOCATION WITH EXPANDED MEMORY
- .%0002! ;WRITTEN 92/04/22 BY ├RAIG ┬RUCE FOR ├= ╚ACKING ╬ET ═AGAZINE
- .%0003! ;--------------------------------------------------------------------
-
- ╘HIS PROGRAM IS WRITTEN FOR THE ┬UDDY ASSEMBLER. ╠IKE MOST ASSEMBLERS, IT
- NEEDS A FEW DIRECTIVES TO START OFF, SO HERE THEY ARE. ╬OTE THAT MY COMMENTS
- COME ┬┼╞╧╥┼ THE SECTION OF CODE THAT ╔ AM COMMENTING ON.
-
- .%0004! .MEM
- .%0005! .BANK 15
- .%0006! .ORG $1300
- .%0007!
- .%0008! ;*** GLOBAL DECLARATIONS
- .%0009!
-
- ╚ERE ARE THE ZERO PAGE LOCATIONS THAT THE PACKAGE USES FOR ITS OWN PURPOSES.
- ╔ STUCK THE SYS╫ORK VARIABLE OVER THE ┬┴╙╔├ GRAPHICS COMMAND PARAMETERS SINCE
- IT SEEMS LIKE A GOOD PLACE. ╔T REQUIRES 16 BYTES AND IS USED BY MOST OF THE
- ROUTINES FOR TEMPORARY STORAGE. "TEMP1" IS USED FOR "VERY" TEMPORARY
- STORAGE.
-
- .%0010! ZP1 = $FA
- .%0011! TEMP1 = $FD
- .%0012! ZW1 = $FE
- .%0013! SYS╫ORK = $80 ;16-BYTE BLOCK
- .%0014!
-
- ╘HESE ARE THE NON-ZERO PAGE STORAGE LOCATIONS. ╘HE COMMON CODE BUFFER PRETTY
- MUCH HAS TO BE AT $200 SINCE THAT IS (ABOUT) THE ONLY FREE SECTION OF MEMORY
- BELOW ADDRESS $0400 (IN THE COMMON MEMORY RANGE).
-
- .%0015! COM├ODE┬UFFER = $200
- .%0016! WORK┬UFFER = $B00
- .%0017!
-
- ╘HESE ARE THE ══╒ CONFIGURATION REGISTER VALUES AND SOME IMPORTANT ╔/╧
- ADDRESSES.
-
- .%0018! BK╙YS = $0E
- .%0019! BK╦ERNEL = $00
- .%0020! BK╙ELECT = $FF00
- .%0021! BK╙ELECT╥AM0 = $FF01
- .%0022! BK╙ELECT╥AM1 = $FF02
- .%0023! BK╥AM0 = $3F
- .%0024! BK╥AM1 = $7F
- .%0025! BK┼XP0 = $80
- .%0026! BK╬ULL = $FF
- .%0027! ZP╙ELECT = $D507
- .%0028! REU = $DF00
- .%0029! VIC = $D000
- .%0030!
- .%0031! ERR╔NSUFFICIENT═EMORY = 1
- .%0032!
- .%0033! ;*** JUMP TO MAIN ROUTINE
- .%0034!
- .%0035! JMP MAIN
- .%0036!
- .%0037! ;*** JUMP TABLE
- .%0038!
-
- ╚ERE'S THAT JUMP TABLE.
-
- .%0039! STARTUP JMP INTERN╙TARTUP
- .%0040! SHUTDOWN JMP INTERN╙HUTDOWN
- .%0041! ZPLOAD JMP INTERN┌P╠OAD
- .%0042! ZPSTORE JMP INTERN┌P╙TORE
- .%0043! FETCH JMP INTERN╥AM0╞ETCH
- .%0044! STASH JMP INTERN╥AM0╙TASH
- .%0045! MALLOC JMP INTERN┴LLOC
- .%0046! FREE JMP INTERN╞REE
- .%0047!
- .%0048! ;*** STORAGE
- .%0049!
-
- ╚ERE ARE SOME USEFUL STORAGE LOCATIONS. "ERRNO" CONTAINS THE CODE FOR THE
- ERROR ENCOUNTERED IN A ROUTINE IF THE ROUTINE EXITS WITH THE CARRY FLAG SET
- (AND IT IS SUPPOSED TO BE CLEARED FOR ╧╦). "N┼XP┬ANKS" GIVES THE NUMBER OF
- EXPANSION MEMORY BANKS, AND "FREE═EMORY" GIVES THE NUMBER OF BYTES CURRENTLY
- FREE IN THE SYSTEM. ┬OTH OF THESE ARE USEFUL STATUS VALUES AND CAN BE READ
- DIRECTLY.
-
- .%0050! ERRNO .BUF 1
- .%0051! N┼XP┬ANKS .BUF 1
- .%0052! MALLOC╚EAD .BUF 3
- .%0053! FREE═EMORY .BUF 3
- .%0054!
- .%0055! ;***STARTUP
- .%0056!
-
- ╘HIS ROUTINE GETS THE BALL ROLLING. ╔T CLEARS THE STATUS REGISTER IN CASE YOU
- START UP THE SYSTEM WITH THE DECIMAL MODE FLAG SET OR INTERRUPTS DISABLED.
-
- .%0057! INTERN╙TARTUP = *
- .%0058! LDA #0
- .%0059! PHA
- .%0060! PLP
- .%0061! LDA #BK╙YS
- .%0062! STA BK╙ELECT
- .%0063! JSR INSTALL├OMMON├ODE
- .%0064! JSR SNIFF╥┼╒
- .%0065! JSR INIT─YNAMIC═EMORY
- .%0066! RTS
- .%0067!
-
- ┴ND THIS ROUTINE STOPS THE BALL FROM ROLLING. ╔ FILL THE ┬┴╙╔├ COMMAND LINE
- BUFFER WITH ZEROS TO STOP THAT SYNTAX ERROR THING.
-
- .%0068! INTERN╙HUTDOWN = *
- .%0069! LDX #0
- .%0070! LDA #0
- .%0071! - STA $200,X
- .%0072! INX
- .%0073! CPX #COM├ODE┼ND-COM├ODE╙TART
- .%0074! BNE -
- .%0075! LDA #BK╦ERNEL
- .%0076! STA BK╙ELECT
- .%0077! RTS
- .%0078!
- .%0079! ;***INSTALL COMMON CODE
- .%0080!
-
- ╘HIS ROUTINE COPIES THE COMMON CODE SUBROUTINES INTO THE COMMON CODE BUFFER
- (AT $0200).
-
- .%0081! INSTALL├OMMON├ODE = *
- .%0082! LDX #0
- .%0083! - LDA COM├ODE╙TART,X
- .%0084! STA COM├ODE┬UFFER,X
- .%0085! INX
- .%0086! CPX #COM├ODE┼ND-COM├ODE╙TART
- .%0087! BCC -
- .%0088! RTS
- .%0089!
- .%0090! ;--------------------------------------------------------------------
- .%0091! ;***COMMON CODE
- .%0092!
-
- ┴ND THIS IS THE COMMON CODE. ╔T CONTAINS FOUR SUBROUTINES FOR ACCESSING ╥┴═1
- (AND THE ZERO PAGE ROUTINES ARE USED FOR ╥┴═0 AS WELL).
-
- .%0093! COM├ODE╙TART = *
- .%0094!
-
- ╙ELECTS THE ══╒ CONFIGURATION ACCORDING TO THE BANK NUMBER AND COPIES THE
- NUMBER OF BYTES REQUIRED FOR A ZPLOAD. ╔T EXITS BY RESTORING THE ╙┘╙ BANK.
- ╘HIS IS USED ONLY FOR INTERNAL MEMORY ZPLOADS.
-
- .%0095! COM┌P╠OAD = *
- .%0096! LDA ZP1+2
- .%0097! STA BK╙ELECT
- .%0098! STY TEMP1
- .%0099! LDY #0
- .%0100! - LDA (ZP1),Y
- .%0101! STA 0,X
- .%0102! INX
- .%0103! INY
- .%0104! CPY TEMP1
- .%0105! BCC -
- .%0106! LDA #BK╙YS
- .%0107! STA BK╙ELECT
- .%0108! RTS
- .%0109!
-
- ╨RETTY MUCH THE SAME AS ZPLOAD.
-
- .%0110! COM┌P╙TORE = *
- .%0111! LDA ZP1+2
- .%0112! STA BK╙ELECT
- .%0113! STY TEMP1
- .%0114! LDY #0
- .%0115! - LDA 0,X
- .%0116! STA (ZP1),Y
- .%0117! INX
- .%0118! INY
- .%0119! CPY TEMP1
- .%0120! BCC -
- .%0121! LDA #BK╙YS
- .%0122! STA BK╙ELECT
- .%0123! RTS
- .%0124!
-
- ┴S THE NAME SUGGESTS, THIS COPIES FROM ╥┴═1 TO ╥┴═0. ╧NLY .┘ NUMBER OF BYTES
- ARE COPIED, AND IF .┘=0, 256 BYTES ARE COPIED. ┘OU'LL NOTICE THAT THE ══╒
- CONFIGURATIONS ARE SWITCHED BETWEEN FOR EVERY BYTE COPIED. ╘HIS IS NOT THE
- MOST EFFICIENT SCHEME, BUT IT SUFFICES. ╘HE ══╒ PRECONFIGURATION REGISTERS
- ARE USED AND THE VALUE THAT ┬┴╙╔├ PUT IN THEM ARE ASSUMED TO STILL BE THERE.
-
- .%0125! COM├OPY╥AM1╘O╥AM0 = *
- .%0126! DEY
- .%0127! BEQ +
- .%0128! - STA BK╙ELECT╥AM1
- .%0129! LDA (ZP1),Y
- .%0130! STA BK╙ELECT╥AM0
- .%0131! STA (ZW1),Y
- .%0132! DEY
- .%0133! BNE -
- .%0134! + STA BK╙ELECT╥AM1
- .%0135! LDA (ZP1),Y
- .%0136! STA BK╙ELECT╥AM0
- .%0137! STA (ZW1),Y
- .%0138! LDA #BK╙YS
- .%0139! STA BK╙ELECT
- .%0140! RTS
- .%0141!
-
- ╘HE OPPOSITE DIRECTION.
-
- .%0142! COM├OPY╥AM0╘O╥AM1 = *
- .%0143! DEY
- .%0144! BEQ +
- .%0145! - STA BK╙ELECT╥AM0
- .%0146! LDA (ZW1),Y
- .%0147! STA BK╙ELECT╥AM1
- .%0148! STA (ZP1),Y
- .%0149! DEY
- .%0150! BNE -
- .%0151! + STA BK╙ELECT╥AM0
- .%0152! LDA (ZW1),Y
- .%0153! STA BK╙ELECT╥AM1
- .%0154! STA (ZP1),Y
- .%0155! LDA #BK╙YS
- .%0156! STA BK╙ELECT
- .%0157! RTS
- .%0158!
-
- ╘HE END OF THE COMMON CODE. ╘HE LENGTH OF THE COMMON CODE IS DETERMINED BY
- SUBTRACTING THE END ADDRESS FROM THE START ADDRESS.
-
- .%0159! COM├ODE┼ND = *
- .%0160!
- .%0161! ;--------------------------------------------------------------------
- .%0162! ;*** ZPLOAD( [ZP1]=╙OURCE, .╪=┌P─EST, .┘=╠ENGTH )
- .%0163!
-
- ╘HE ACTUAL ZPLOAD ROUTINE. ╔T DISPATCHES TO THE COMMON CODE ROUTINE IF
- INTERNAL MEMORY IS SPECIFIED BY THE FAR POINTER, OR FALLS THROUGH TO ╥┼╒ CODE
- IF EXPANSION MEMORY IS SPECIFIED.
-
- .%0164! INTERN┌P╠OAD = *
- .%0165! LDA ZP1+2
- .%0166! BMI +
- .%0167! JMP COM┌P╠OAD-COM├ODE╙TART+COM├ODE┬UFFER
- .%0168! + STY REU+7
- .%0169! LDY #$91
- .%0170!
-
- ╙ETS UP THE ╥┼╒ ├ONTROLLER REGISTERS FOR THE PARAMETERS OF THE TRANSFER. ╬OTE
- THAT THE VALUE OF THE ZERO PAGE ADDRESS IS NOT ASSUMED TO BE ABSOLUTE $0000
- BUT IS TAKEN FROM THE ZERO PAGE SELECTION REGISTER OF THE ══╒. ╘HE ╥┼╒
- ├ONTROLLER DOES NOT USE THE ══╒ FOR DECODING ZERO PAGE AND STACK PAGE
- ADDRESSES; IT ACCESSES THE ABSOLUTE MEMORY DIRECTLY.
-
- .%0171! ZERO╨AGE╥EU╧P = *
- .%0172! STA REU+6
- .%0173! STX REU+2
- .%0174! LDA ZP╙ELECT
- .%0175! STA REU+3
- .%0176! LDA ZP1
- .%0177! STA REU+4
- .%0178! LDA ZP1+1
- .%0179! STA REU+5
- .%0180! LDA #0
- .%0181! STA REU+8
-
- ╚ERE THE SYSTEM CLOCK SPEED IS PUT INTO ╙LOW MODE WHILE THE TRANSFER OCCURS
- AND IS THEN RESTORED. ╘HIS IS NECESSARY.
-
- .%0182! LDA VIC+$30
- .%0183! LDX #$00
- .%0184! STX VIC+$30
- .%0185! STY REU+1
- .%0186! STA VIC+$30
- .%0187! RTS
- .%0188!
- .%0189! ;*** ZPSTORE( .╪=┌P╙OURCE, [ZP1]=─EST, .┘=╠ENGTH )
- .%0190!
-
- ╨RETTY MUCH THE SAME AS THE ZPLOAD ROUTINE, EXCEPT THAT A COMMAND CODE FOR THE
- ╥┼╒ ├ONTROLLER IS DIFFERENT (SPECIFYING AN INTERNAL TO EXPANSION MEMORY
- TRANSFER). ╘HE ╥┼╒ CODE IN THE ZPLOAD ROUTINE IS CALLED.
-
- .%0191! INTERN┌P╙TORE = *
- .%0192! LDA ZP1+2
- .%0193! BMI +
- .%0194! JMP COM┌P╙TORE-COM├ODE╙TART+COM├ODE┬UFFER
- .%0195! + STY REU+7
- .%0196! LDY #$90
- .%0197! JMP ZERO╨AGE╥EU╧P
- .%0198!
- .%0199! ;--------------------------------------------------------------------
-